﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DocumentsTagger.DM;


namespace DocumentsTagger.DAL
{
    /// <summary>
    /// Interface that enables the quick replacing of DAL layer.
    /// </summary>
    public interface ITaggerDal
    {
        /// <summary>
        /// Creates an empty DB for future use.
        /// </summary>
        void CreateEmptyDB();

        #region scanned directories
        /// <summary>
        /// Gets the list of documents to be scanned
        /// </summary>
        /// <returns>A list of documents which were configured to be scanned</returns>
        List<String> GetScannedDirectories();

        /// <summary>
        /// Adds a directory to the scanning mechanizm
        /// </summary>
        /// <param name="path">full  path to the folder to be scanned</param>
        void AddScannedDirectory(string path);

        /// <summary>
        /// removes a directory from the scanning mechanizm
        /// </summary>
        /// <param name="path">full path to the folder to be removed</param>
        void RemoveScannedDirectory(string path);
        #endregion 

        #region document managment
        /// <summary>
        /// check if a document exists in the DB
        /// </summary>
        /// <param name="PathToFile">A full path to the file</param>
        /// <returns>true if the file exists, false otherwise</returns>
        bool DocumentExists(string PathToFile);

        /// <summary>
        /// adds a new document to the DB
        /// </summary>
        /// <param name="document">Document object</param>
        void AddDocument(Document document);

        /// <summary>
        /// adds a new document to the DB
        /// </summary>
        /// <param name="document">Document object</param>
        /// <param name="acceptedTagsList">list of accepted tags for this document</param>
        /// <param name="suggestedTagsList">list of suggested tags for this document</param>
        /// <param name="declinedTagsList">list of declined tags for this document</param>
        void AddDocument(Document document, List<Tag> acceptedTagsList, List<Tag> suggestedTagsList, List<Tag> declinedTagsList);

        /// <summary>
        /// removes a document from db
        /// </summary>
        /// <param name="document">the document to remove from the DB</param>
        void RemoveDocument(Document document);
        #endregion 

        #region document retrieval
        /// <summary>
        /// gets the documents in the DB
        /// </summary>
        /// <returns>list of all currently available documents</returns>
        List<Document> GetDocuments();

        /// <summary>
        /// gets the documents having a specific tag
        /// </summary>
        /// <param name="tag">the tag to search for</param>
        /// <returns>list of documents having such tag</returns>
        List<Document> GetDocumentsByTag(Tag tag);

        /// <summary>
        /// gets the documents having a specific accepted tag
        /// </summary>
        /// <param name="tag">the tag to search for</param>
        /// <returns>list of documents having such tag</returns>
        List<Document> GetDocumentsByAcceptedTag(Tag tag);

        /// <summary>
        /// gets the documents having a specific declined tag
        /// </summary>
        /// <param name="tag">the tag to search for</param>
        /// <returns>list of documents having such tag</returns>
        List<Document> GetDocumentsByDeclinedTag(Tag tag);
        #endregion 
        
        #region tag managment
        /// <summary>
        /// add a tag to tag repository
        /// </summary>
        /// <param name="tag">the tag to add</param>
        void AddTag(Tag tag);

        /// <summary>
        /// searches for a tag in the system
        /// </summary>
        /// <param name="tagValue">the name of the tag to check</param>
        /// <returns>true if there is such a tag, false otherwise</returns>
        bool HasTag(string tagValue);

        /// <summary>
        /// searches for a tag in the system
        /// </summary>
        /// <param name="tagValue">the name of the tag to check</param>
        /// <param name="tag">the matching tag object</param>
        /// <returns>true if there is such a tag, false otherwise</returns>
        bool HasTag(string tagValue, out Tag tag);
        #endregion
        
        #region tag retrieval
        /// <summary>
        /// gets all the tags in the system
        /// </summary>
        /// <returns>list of all currently available tags</returns>
        List<Tag> GetTags();

        /// <summary>
        /// gets the declined tag of a document
        /// </summary>
        /// <param name="document">the document to check</param>
        /// <returns>a list of declined tags for specified document</returns>
        List<Tag> GetDocumentDeclinedTags(Document document);

        /// <summary>
        /// gets the suggested tag of a document
        /// </summary>
        /// <param name="document">the document to check</param>
        /// <returns>a list of suggested tags for specified document</returns>
        List<Tag> GetDocumentSuggestedTags(Document document);

        /// <summary>
        /// gets the accepted tag of a document
        /// </summary>
        /// <param name="document">the document to check</param>
        /// <returns>a list of accepted tags for specified document</returns>
        List<Tag> GetDocumentAcceptedTags(Document document);
        #endregion

        #region tag of document management
        /// <summary>
        /// removes an accepted tag from a document
        /// </summary>
        /// <param name="document">the document to remove the tag from</param>
        /// <param name="tag">the tag to remove from the document</param>
        void RemoveAcceptedTagFromDocument(Document document, Tag tag);

        /// <summary>
        /// removes an declined tag from a document
        /// </summary>
        /// <param name="document">the document to remove the tag from</param>
        /// <param name="tag">the tag to remove from the document</param>
        void RemoveDeclinedTagFromDocument(Document document, Tag tag);

        /// <summary>
        /// decline a tag from suggestion of a document
        /// </summary>
        /// <param name="document">the document to remove the suggestion from</param>
        /// <param name="tag">the tag to remove from the document</param>
        void DeclineSuggestedTagFromDocument(Document document, Tag tag);

        /// <summary>
        /// add a tag to a document
        /// </summary>
        /// <param name="document">the document to add the tag to</param>
        /// <param name="tag">the tag to remove from the document</param>
        void AddAcceptedTagToDocument(Document document, Tag tag);

        /// <summary>
        /// add a tag to suggestion for a document
        /// </summary>
        /// <param name="document">the document to add the suggestion to</param>
        /// <param name="tag">the tag to add to the document</param>
        void AddSuggestedTagToDocument(Document document, Tag tag);

        /// <summary>
        /// add a declined tag to document
        /// </summary>
        /// <param name="document">the document to remove the suggestion from</param>
        /// <param name="tag">the tag to remove from the document</param>
        void AddDeclinedTagToDocument(Document document, Tag tag);

        /// <summary>
        /// removes a tag from suggestion of a document
        /// </summary>
        /// <param name="document">the document to remove the suggestion from</param>
        /// <param name="tag">the tag to remove from the document</param>
        void RemoveSuggestedTagFromDocument(Document document, Tag tag);
        #endregion 
    }
}
